package com.base.filter;

import com.base.api.uum.UumUserService;
import com.base.dao.uum.UumUserLoginLogMapper;
import com.base.dao.uum.UumUserMapper;
import com.base.utils.CookieUtils;
import com.base.utils.TokenUtils;
import com.base.vo.uum.UumUser;
import com.base.vo.uum.UumUserLoginLog;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UserFilter implements Filter {

    /**
     * 封装，不需要过滤的list列表
     */
    protected static List<Pattern> patterns = new ArrayList<>();

    private String prersonPassUrl = "css.*,lib.*,image.*,js.*";
    private String[] prersonPassUrls;

    @Value("${loginPath:html/page/login}")
    private String loginPath;

    @Value("${server.needLogin:false}")
    private Boolean needLogin;

    @Value("${druid.url}")
    private String druidUrl;

    private static final Logger logger = LoggerFactory.getLogger(UserFilter.class);

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Autowired
    private UumUserMapper uumUserMapper;

    @Autowired
    private UumUserLoginLogMapper uumUserLoginLogMapper;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
//        if (loginPath != null) {
//            patterns.add(Pattern.compile(loginPath + ".*"));
//        }
        prersonPassUrls = prersonPassUrl.split(",");
        for (String url : prersonPassUrls) {
            Pattern p = Pattern.compile(url);
            patterns.add(p);
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String url = req.getRequestURI().substring(req.getContextPath().length());
        logger.debug(url);
        if (url.startsWith("/") && url.length() > 1) {
            url = url.substring(1);
        }
        if (isInclude(url) || url.endsWith(".js") || url.endsWith(".css") || url.startsWith("/images") || url.contains("sql") || url.contains("druid")) {
            filterChain.doFilter(req, resp);
        } else {

            HttpSession session = req.getSession();
            String token = (String) session.getAttribute(UumUserService.TOKENKEY);
            UumUserLoginLog userLoginLog = new UumUserLoginLog();
            if(token ==null && !StringUtils.isBlank(CookieUtils.getCookie(req,UumUserService.TOKENKEY)) && !StringUtils.isBlank(CookieUtils.getCookie(req,"cookie_userName"))){
                UumUser uumUser1 = uumUserMapper.selectByUserName(CookieUtils.getCookie(req,"cookie_userName"));
                if(uumUser1!=null){
                    token = CookieUtils.getCookie(req,UumUserService.TOKENKEY);
                    session.setAttribute(UumUserService.TOKENKEY,token);
                    session.setAttribute("user",uumUser1);
                    userLoginLog.setLoginDate(new Date());
                    userLoginLog.setLoginHost(req.getRemoteHost());
                    userLoginLog.setLoginType("1");
                    userLoginLog.setLoginName(uumUser1.getUserName());
                    userLoginLog.setLoginToken(token);
                }
            }
            if (token != null && TokenUtils.verify(token) && redisTemplate.hasKey("uum::loginUser") && redisTemplate.opsForHash().hasKey("uum::loginUser",token)) {
                //校验通过
                // session存在
                if(userLoginLog.getLoginName()!=null && !StringUtils.isBlank(userLoginLog.getLoginName())){
                    uumUserLoginLogMapper.insertSelective(userLoginLog);
                }
                if(url.endsWith("login")){
                    resp.sendRedirect(req.getContextPath() + "/");
                }
                filterChain.doFilter(req, resp);
            } else  {
                if(needLogin && !url.endsWith("login")){
                    resp.setHeader("loginStaus","timeout");
                    resp.sendRedirect(req.getContextPath() + "/" + loginPath);
                    return;
                }else {
                    filterChain.doFilter(req, resp);
                }

            }

        }
    }

    /**
     * 是否需要过滤
     *
     * @param url
     * @return
     */
    private boolean isInclude(String url) {
        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(url);
            if (matcher.matches()) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void destroy() {

    }
}
